// SPDX-License-Identifier: Mulan PSL v2
/*
 * Copyright (c) 2025 Huawei Technologies Co., Ltd.
 * This software is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *         http://license.coscl.org.cn/MulanPSL2
 *
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */

use std::error::Error as StdError;

use thiserror::Error;

use super::Framer;

/// Errors that can occur by `RawFramer`.
#[derive(Debug, Error)]
pub enum RawFramerError {
    #[error("insufficient buffer capacity (required: {required}, capacity: {capacity})")]
    InsufficientBuffer { required: usize, capacity: usize },

    #[error("failed to write frame payload")]
    WritePayload(#[source] Box<dyn StdError + Send + Sync + 'static>),
}

/// A "no-op" framer that treats the entire buffer as a single frame.
#[derive(Debug, Default, Clone, Copy)]
pub struct RawFramer;

impl Framer for RawFramer {
    type Error = RawFramerError;

    fn header_len(&self) -> usize {
        0
    }

    fn prepare_buffer<'a>(
        &self,
        buff: &'a mut [u8],
    ) -> Result<(&'a mut [u8], &'a mut [u8]), Self::Error> {
        Ok(buff.split_at_mut(0))
    }

    fn encode_frame<'a>(
        &self,
        header: &'a mut [u8],
        payload: &'a [u8],
    ) -> Result<usize, Self::Error> {
        Ok(header.len() + payload.len())
    }

    fn decode_frame<'a>(&self, buff: &'a [u8]) -> Result<Option<(usize, &'a [u8])>, Self::Error> {
        Ok(Some((buff.len(), buff)))
    }
}
